import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect as reduxConnect } from 'react-redux';
import {
  withRouter,
  matchPath,
} from 'react-router-dom';
import { isRoot, dynamicTenantsUrl } from 'stripes-config';
import localforage from 'localforage';

import { ConnectContext } from '@folio/stripes-connect';
import {
  requestLogin,
  requestSSOLogin,
} from '../../loginServices';
import { setAuthError } from '../../okapiActions';
import Login from './Login';

class LoginCtrl extends Component {
  static propTypes = {
    authFailure: PropTypes.arrayOf(PropTypes.object),
    ssoEnabled: PropTypes.bool,
    autoLogin: PropTypes.shape({
      username: PropTypes.string.isRequired,
      password: PropTypes.string.isRequired,
    }),
    clearAuthErrors: PropTypes.func.isRequired,
    history: PropTypes.shape({
      push: PropTypes.func.isRequired,
    }).isRequired,
    location: PropTypes.shape({
      pathname: PropTypes.string.isRequired,
    }).isRequired,
  };

  static contextType = ConnectContext;

  constructor(props) {
    super(props);
    this.sys = require('stripes-config'); // eslint-disable-line global-require
    this.okapiUrl = this.sys.okapi.url;
    this.tenant = this.sys.okapi.tenant;
    this.state = {
      loading: false,
      loginFailureMsg: '',
      tenants: [],
    }
    // if (props.autoLogin && props.autoLogin.username) {
    //   this.handleSubmit(props.autoLogin);
    // }
  }

  handleTenants = async () => {
    if (!isRoot) return;

    try {
      const response = await fetch(dynamicTenantsUrl, {
        headers: { 'X-Okapi-Tenant': 'null' }
      })
      const { data } = await response.json()

      const tenantOptions = [this.sys.okapi, ...data].map(item => {
        if (item.url) {
          return {
            ...item,
            label: item.tenant || item.fullName,
            value: item.tenant || item.organizationCode,
            tenant: item.tenant || item.organizationCode,
            locale: this.sys.okapi.locale,
          };
        }
        return {
          ...item,
          label: item.fullName,
          value: item.organizationCode,
          tenant: item.organizationCode,
          url: this.okapiUrl,
          locale: this.sys.okapi.locale,
        };
      });
      this.setState({ tenants: tenantOptions });
    } catch (error) {
      console.error(error)
    }
  }

  componentDidMount() {
    this.handleTenants()
  }

  componentWillUnmount() {
    this.props.clearAuthErrors();
  }

  handleSuccessfulLogin = () => {
    if (matchPath(this.props.location.pathname, '/login')) {
      this.props.history.push('/');
    }
  }

  handleSubmit = async (data) => {
    this.setState({ loading: true });

    if (!isRoot) {
      return requestLogin(this.okapiUrl, this.context.store, this.tenant, data)
        .then(this.handleSuccessfulLogin)
        .catch(e => {
          this.setState({ loginFailureMsg: e.toString() });
          console.error(e); // eslint-disable-line no-console
        })
        .finally(() => {
          this.setState({ loading: false });
        });
    }

    const { okapi } = this.props.stripes;
    const { username, password, ...rest } = data;

    const okapiInfo = {};

    if (rest.tenant !== okapi.tenant) {
      Object.assign(okapiInfo, rest);
      localforage.setItem('curTenant', rest);
    } else {
      Object.assign(okapiInfo, okapi);
    }

    // return requestLogin(this.okapiUrl, this.context.store, this.tenant, { username, password })
    return requestLogin(okapiInfo.url, this.context.store, okapiInfo.tenant, { username, password })
      .then(this.handleSuccessfulLogin)
      .catch(e => {
        this.setState({ loginFailureMsg: e.toString() });
        console.error(e); // eslint-disable-line no-console
      })
      .finally(() => {
        this.setState({ loading: false });
      });
  }

  handleSSOLogin = () => {
    requestSSOLogin(this.okapiUrl, this.tenant);
  }

  render() {
    const { authFailure, ssoEnabled } = this.props;

    return (
      <Login
        loading={this.state.loading}
        onSubmit={this.handleSubmit}
        authErrors={authFailure}
        handleSSOLogin={this.handleSSOLogin}
        ssoActive={ssoEnabled}
        loginFailureMsg={this.state.loginFailureMsg}
        tenants={this.state.tenants}
      />
    );
  }
}

const mapStateToProps = state => ({
  authFailure: state.okapi.authFailure,
  ssoEnabled: state.okapi.ssoEnabled,
});
const mapDispatchToProps = dispatch => ({
  clearAuthErrors: () => dispatch(setAuthError([])),
});

export default reduxConnect(mapStateToProps, mapDispatchToProps)(withRouter(LoginCtrl));
